from queue import Queue
from multiprocessing import Queue as ProcQueue
from typing import Optional
import time


class Debug:

    def __init__(self, queues, time_switch: bool = False, debug_name: str = 'System',
                 time_format: str = '%H:%M:%S', file_name=None, color=None):
        self.__stat = True
        self.__color = color
        self.__colorDict = {
            'black': 40, 'red': 41, 'green': 42, 'yellow': 43, 'blue': 44, 'purple': 45,
            'blue2': 46, 'white': 47
        }
        self.__styleDict = {
            'normal': 0, 'highlight': 1, 'underline': 4, 'flash': 5, 'reverse': 7, 'division': 8
        }
        if queues is not None:
            self.debugName = debug_name
            self.timeFormat = time_format
            self.__timeSwitch = time_switch
            self.__Q = queues
            self.__fileName = file_name
            if self.__fileName is not None:
                with open(self.__fileName, "w+") as fp:
                    fp.write(f"===== [{debug_name}] =====\n")
                    fp.close()
        else:
            self.__stat = False

    def debug(self, strs: str, style: str = 'normal') -> None:
        """
        向日志管道中输入调试信息，并向标准输出打印调试信息
        Args:
            strs: 信息文本
            style: 文本模式，符合print特性

        Returns:
            无
        """
        if self.__stat:
            status = '关注'
            if not self.__timeSwitch:
                info_text = '[{}-{}]--> {}'.format(self.debugName, status, strs)
            else:
                info_text = '[{}-{}-{}]--> {}'.format(self.debugName,
                                                      time.strftime(self.timeFormat, time.localtime(time.time())),
                                                      status, strs)
            if self.__fileName is not None:
                with open(self.__fileName, "a+") as fp:
                    fp.write(info_text + '\n')
                    fp.close()
            if self.__color is None:
                back_color = 'm'
            else:
                back_color = str(self.__colorDict[self.__color]) + 'm'
            style_font = self.__styleDict[style]
            info_text = f"\033[{style_font};32{back_color} {info_text} \033[0m"
            if not self.__Q.full():
                self.__Q.put(info_text)
            else:
                self.__Q.get()
                self.__Q.put(info_text)
            print(info_text)
        else:
            pass

    def info(self, strs, style: str = 'normal') -> None:
        """
        向日志管道中输入普通信息，并向标准输出打印普通信息
        Args:
            strs: 信息文本
            style: 文本模式，符合print特性

        Returns:
            无
        """
        if self.__stat:
            status = '信息'
            if not self.__timeSwitch:
                info_text = '[{}-{}]--> {}'.format(self.debugName, status, strs)
            else:
                info_text = '[{}-{}-{}]--> {}'.format(self.debugName,
                                                      time.strftime(self.timeFormat, time.localtime(time.time())),
                                                      status, strs)
            if self.__fileName is not None:
                with open(self.__fileName, "a+") as fp:
                    fp.write(info_text + '\n')
                    fp.close()
            if self.__color is None:
                back_color = 'm'
            else:
                back_color = str(self.__colorDict[self.__color]) + 'm'
            style_font = self.__styleDict[style]
            info_text = f"\033[{style_font}:37{back_color} {info_text} \033[0m"
            if not self.__Q.full():
                self.__Q.put(info_text)
            else:
                self.__Q.get()
                self.__Q.put(info_text)
            print(info_text)
        else:
            pass

    def error(self, strs, style: str = 'normal') -> None:
        """
        向日志管道中输入错误信息，并向标准输出打印错误信息
        Args:
            strs: 信息文本
            style: 文本模式，符合print特性

        Returns:
            无
        """
        if self.__stat:
            status = '错误'
            if not self.__timeSwitch:
                info_text = '[{}-{}]--> {}'.format(self.debugName, status, strs)
            else:
                info_text = '[{}-{}-{}]--> {}'.format(self.debugName,
                                                      time.strftime(self.timeFormat, time.localtime(time.time())),
                                                      status, strs)
            if self.__fileName is not None:
                with open(self.__fileName, "a+") as fp:
                    fp.write(info_text + '\n')
                    fp.close()
            if self.__color is None:
                back_color = 'm'
            else:
                back_color = str(self.__colorDict[self.__color]) + 'm'
            style_font = self.__styleDict[style]
            info_text = f"\033[{style_font};31{back_color} {info_text} \033[0m"
            if not self.__Q.full():
                self.__Q.put(info_text)
            else:
                self.__Q.get()
                self.__Q.put(info_text)
            print(info_text)
        else:
            pass

    def warn(self, strs, style: str = 'normal') -> None:
        """
        向日志管道中输入警告信息，并向标准输出打印警告信息
        Args:
            strs: 信息文本
            style: 文本模式，符合print特性

        Returns:
            无
        """
        if self.__stat:
            status = '警告'
            if not self.__timeSwitch:
                info_text = '[{}-{}]--> {}'.format(self.debugName, status, strs)
            else:
                info_text = '[{}-{}-{}]--> {}'.format(self.debugName,
                                                      time.strftime(self.timeFormat, time.localtime(time.time())),
                                                      status, strs)
            if self.__fileName is not None:
                with open(self.__fileName, "a+") as fp:
                    fp.write(info_text + '\n')
                    fp.close()
            if self.__color is None:
                back_color = 'm'
            else:
                back_color = str(self.__colorDict[self.__color]) + 'm'
            style_font = self.__styleDict[style]
            info_text = f"\033[{style_font};33{back_color} {info_text} \033[0m"
            if not self.__Q.full():
                self.__Q.put(info_text)
            else:
                self.__Q.get()
                self.__Q.put(info_text)
            print(info_text)
        else:
            pass

    def exception(self, strs: str, style: str = 'normal') -> Optional[Exception]:
        """
        向日志管道中输入异常信息，并返回一个异常实例
        Args:
            strs: 文本信息
            style: 文本模式，符合print特性

        Returns:
            异常 | None
        """
        if self.__stat:
            status = '异常'
            if not self.__timeSwitch:
                info_text = '[{}-{}]--> {}'.format(self.debugName, status, strs)
            else:
                info_text = '[{}-{}-{}]--> {}'.format(self.debugName,
                                                      time.strftime(self.timeFormat, time.localtime(time.time())),
                                                      status, strs)
            if self.__fileName is not None:
                with open(self.__fileName, "a+") as fp:
                    fp.write(info_text + '\n')
                    fp.close()
            if self.__color is None:
                back_color = 'm'
            else:
                back_color = str(self.__colorDict[self.__color]) + 'm'
            style_font = self.__styleDict[style]
            info_text = f"\033[{style_font};31{back_color} {info_text} \033[0m"
            if not self.__Q.full():
                self.__Q.put(info_text)
            else:
                self.__Q.get()
                self.__Q.put(info_text)
            return Exception(info_text)
        else:
            return None

    def getInfo(self):
        if self.__stat:
            if not self.__Q.empty():
                res = self.__Q.get()
                return res
            else:
                return None
        else:
            return None
